#-------------------------------------------------------------------------------
# Name:        pci
# Purpose:
#
# Author:      SUPER_紫电  QQ:911344755
#
# Created:     23/08/2022
# Copyright:   (c) SUPER_紫电 2022 All rights reserved.
# Licence:     <Modified BSD licence>
#-------------------------------------------------------------------------------

PCI_MAX_BUS = 255 # 8 bits (0 ~ 255)
PCI_MAX_DEV = 31 # 5 bits (0 ~ 31)
PCI_MAX_FUN = 7 # 3 bits (0 ~ 7)

CONFIG_ADDRESS = 0xCF8
CONFIG_DATA    = 0xCFC

PCICFG_REG_VID           = 0x00 # Vendor id, 2 bytes
PCICFG_REG_DID           = 0x02 # Device id, 2 bytes
PCICFG_REG_CMD           = 0x04 # Command register, 2 bytes
PCICFG_REG_STAT          = 0x06 # Status register, 2 bytes
PCICFG_REG_RID           = 0x08 # Revision id, 1 byte
PCICFG_REG_PROG_INTF     = 0x09 # Programming interface code, 1 byte
PCICFG_REG_SUBCLASS      = 0x0A # Sub-class code, 1 byte
PCICFG_REG_BASCLASS      = 0x0B # Base class code, 1 byte
PCICFG_REG_CACHE_LINESZ  = 0x0C # Cache line size, 1 byte
PCICFG_REG_LATENCY_TIMER = 0x0D # Latency timer, 1 byte
PCICFG_REG_HEADER_TYPE   = 0x0E # Header type, 1 byte
PCICFG_REG_BIST          = 0x0F # Builtin self test, 1 byte
PCICFG_REG_BAR0          = 0x10 # Base addr register 0, 4 bytes
PCICFG_REG_BAR1          = 0x14 # Base addr register 1, 4 bytes
PCICFG_REG_BAR2          = 0x18 # Base addr register 2, 4 bytes
PCICFG_REG_BAR3          = 0x1C # Base addr register 3, 4 bytes
PCICFG_REG_BAR4          = 0x20 # Base addr register 4, 4 bytes
PCICFG_REG_BAR5          = 0x24 # Base addr register 5, 4 bytes
PCICFG_REG_CIS           = 0x28 # Cardbus CIS Pointer
PCICFG_REG_SVID          = 0x2C # Subsystem Vendor ID, 2 bytes
PCICFG_REG_SDID          = 0x2E # Subsystem ID, 2 bytes
PCICFG_REG_ROMBAR        = 0x30 # ROM base register, 4 bytes
PCICFG_REG_CAPPTR        = 0x34 # Capabilities pointer, 1 byte
PCICFG_REG_INT_LINE      = 0x3C # Interrupt line, 1 byte
PCICFG_REG_INT_PIN       = 0x3D # Interrupt pin, 1 byte
PCICFG_REG_MIN_GNT       = 0x3E # Minimum grant, 1 byte
PCICFG_REG_MAX_LAT       = 0x3F # Maximum lat, 1 byte

#-----------------------------------------------------------------------------
#
# Support Macros
#
#-----------------------------------------------------------------------------

# Bus Number, Device Number and Function Number to PCI Device Address
def pci_bus_dev_func(bus, dev, func):
    return ((bus & 0xFF) << 8) | ((dev & 0x1F) << 3) | (func & 7)

# PCI Device Address to Bus Number
def pci_get_bus(address):
    return (address >> 8) & 0xFF

# PCI Device Address to Device Number
def pci_get_dev(address):
    return (address >> 3) & 0x1F

# PCI Device Address to Function Number
def pci_get_func(address):
    return address & 7
